{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1. 目的\n",
      "为加强公司内部管理，有效进行资金控制，降低资金风险，规范公司财务借 款报销行为，根据国家相关法律法规及公司财务管理需要和实际情况，特制订本 办法。\n",
      "2. 依据\n",
      "根据国家相关的财经制度及公司的实际情况，分别说明报销相关的借款流程 及各项支出具体的财务报销制度和报销流程，制定本办法。\n",
      "3.适用范围\n",
      "本制度适用于公司各部门，与公司建立劳动关系、劳务关系、实习关系的全 体员工，分(子)公司可参照执行。\n",
      "4.职责\n",
      "各部门/分(子)公司/项目组应当加强对本单位员工出差活动和费用报销的 内控管理，对本单位出差审批、费用报销规模控制负责，财务人员等对员工借款、 费用报销进行审核把关并确认票据的完整、合规。\n",
      "第二部分借款管理及流程\n",
      "1. 员工借款管理规定\n",
      "员工借款限于一次性支付3000元以上公司专项业务及项目所需物资的采 购。借款实行“前款不清，后款不借”原则，借款人应于事后20个工作日内按 报销程序办理报销还款手续。逾期没有报销结账的，将直接从其应发工资、奖金 或其他报销款中扣还，直到扣清为止。因工作需要必须同时产生多项借款的，由 公司领导批复后特殊处理。\n",
      "2. 员工借款流程\n",
      "借款人在员工自助服务门户上填写借款申请，内容包含：借款人姓名、借款 用途、借款金额、借款事由，财务负责借款审批及借款资金发放。\n",
      "第三部分日常费用报销制度及流程\n",
      "1. 日常费用报销管理规定\n",
      "日常费用报销包括差旅报销及一般报销。差旅报销包括出差交通工具费、交 通费及住宿费；一般报销包括招待费、市内交通费、租车费、购书费、办公费、 打印费、团建费、工作餐等。\n"
     ]
    }
   ],
   "source": [
    "from docx import Document #pip install python-docx\n",
    "\n",
    "# 第一步：遍例文档，读取段落paragraphs #\n",
    "def read_docx_paragraphs(file_path):\n",
    "    document = Document(file_path)\n",
    "    paragraphs = []\n",
    "    # 遍历文档中的所有段落\n",
    "    for para in document.paragraphs:\n",
    "        if para.text != \"\":     # 去掉空行\n",
    "            paragraphs.append(para.text)\n",
    "           # print(para.text)\n",
    "    return paragraphs\n",
    "\n",
    "file_path = 'Data/财务报销办法6.0.docx'\n",
    "para = read_docx_paragraphs(file_path)\n",
    "print('\\n'.join(para[4:20]))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['ID_001: 制度编号： SUNBOX-FIN-05',\n",
       " 'ID_002: 财务报销管理办法',\n",
       " 'ID_003: 北京尚博信科技有限公司 2021年04月15日颁',\n",
       " 'ID_004: 第一部分总则',\n",
       " 'ID_005: 1. 目的',\n",
       " 'ID_006: 为加强公司内部管理，有效进行资金控制，降低资金风险，规范公司财务借 款报销行为，根据国家相关法律法规及公司财务管理需要和实际情况，特制订本 办法。',\n",
       " 'ID_007: 2. 依据',\n",
       " 'ID_008: 根据国家相关的财经制度及公司的实际情况，分别说明报销相关的借款流程 及各项支出具体的财务报销制度和报销流程，制定本办法。',\n",
       " 'ID_009: 3.适用范围',\n",
       " 'ID_010: 本制度适用于公司各部门，与公司建立劳动关系、劳务关系、实习关系的全 体员工，分(子)公司可参照执行。',\n",
       " 'ID_011: 4.职责',\n",
       " 'ID_012: 各部门/分(子)公司/项目组应当加强对本单位员工出差活动和费用报销的 内控管理，对本单位出差审批、费用报销规模控制负责，财务人员等对员工借款、 费用报销进行审核把关并确认票据的完整、合规。',\n",
       " 'ID_013: 第二部分借款管理及流程',\n",
       " 'ID_014: 1. 员工借款管理规定',\n",
       " 'ID_015: 员工借款限于一次性支付3000元以上公司专项业务及项目所需物资的采 购。借款实行“前款不清，后款不借”原则，借款人应于事后20个工作日内按 报销程序办理报销还款手续。逾期没有报销结账的，将直接从其应发工资、奖金 或其他报销款中扣还，直到扣清为止。因工作需要必须同时产生多项借款的，由 公司领导批复后特殊处理。',\n",
       " 'ID_016: 2. 员工借款流程',\n",
       " 'ID_017: 借款人在员工自助服务门户上填写借款申请，内容包含：借款人姓名、借款 用途、借款金额、借款事由，财务负责借款审批及借款资金发放。',\n",
       " 'ID_018: 第三部分日常费用报销制度及流程',\n",
       " 'ID_019: 1. 日常费用报销管理规定',\n",
       " 'ID_020: 日常费用报销包括差旅报销及一般报销。差旅报销包括出差交通工具费、交 通费及住宿费；一般报销包括招待费、市内交通费、租车费、购书费、办公费、 打印费、团建费、工作餐等。']"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 第二步：把paragraphs格式化为ID_001: <text>的格式\n",
    "def paragraphs_with_id(para):\n",
    "    \"\"\"\n",
    "    加工一个字符串数组para，使得每个字符串前面都带有递增的ID前缀。\n",
    " \n",
    "    函数内部逻辑:\n",
    "    - 使用enumerate从1开始为数组元素生成索引。\n",
    "    - 使用格式化字符串生成ID前缀，确保ID是三位数字，如\"001\"。\n",
    "    \"\"\"\n",
    "    formatted_paras = []\n",
    "    for index, text in enumerate(para, start=1):\n",
    "        # 生成格式化的ID前缀，例如\"ID_001\"\n",
    "        formatted_id = f\"ID_{index:03d}\"\n",
    "        # 打印带有ID前缀的字符串\n",
    "        formatted_paras.append(f\"{formatted_id}: {text}\")\n",
    "    return formatted_paras\n",
    "\n",
    "# 测试用例\n",
    "paragraphs_with_id(para[:20])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ID_024\n"
     ]
    }
   ],
   "source": [
    "# 第三步：让大模型分块，找出从哪块分割其对应的ID_XXX\n",
    "from openai import OpenAI\n",
    "\n",
    "client = OpenAI(\n",
    "    api_key=\"ollama\",\n",
    "    base_url=\"http://192.168.20.43:11434/v1\"\n",
    ")\n",
    "\n",
    "def llm_chunking_prompt(chunks):\n",
    "    prompt = f\"\"\"\\\n",
    "    ---------------------\\\n",
    "    # PROMPT #\\\n",
    "    You will receive as input an document with paragraphs identified by 'ID_XXX:<test>'\\\n",
    "    ---------------------\\\n",
    "    # TASK #\\\n",
    "    Find the first paragraph(not the first one) where the content clearly changes compared to the previous paragraphs.\\\n",
    "    ---------------------\\\n",
    "    # OUTPUT #\\\n",
    "    Return the ID of the paragraph with the content shift as in the exemplified format:'ID_XXX'\\\n",
    "    ---------------------\\\n",
    "    # Additional Considerations #\\\n",
    "    Avoid very long groups of paragraphs. Aim for a good balance between identifying content shifts and keeping groups manageable.\\\n",
    "    ---------------------\\\n",
    "    \"\"\"\n",
    "    chunks_with_id = paragraphs_with_id(chunks)\n",
    "    # 在每个段落后面添加换行符，并创建一个新的列表\n",
    "    new_chunks_with_id = [chunk + '\\n' for chunk in chunks_with_id]\n",
    "\n",
    "    # 使用 join 方法将新列表中的元素连接成一个单一的字符串\n",
    "    query = ''.join(new_chunks_with_id)\n",
    "\n",
    "    completion = client.chat.completions.create(\n",
    "        model=\"qwen2-7b-instruct\",\n",
    "        messages=[{'role': 'system', 'content': prompt},\n",
    "                  {'role': 'user', 'content': query}],\n",
    "        )\n",
    "    return completion.choices[0].message.content\n",
    "\n",
    "# 测试用例\n",
    "summary_text = llm_chunking_prompt(para[:30]) \n",
    "print(summary_text)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "ename": "ModuleNotFoundError",
     "evalue": "No module named 'openai'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[5], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mopenai\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m OpenAI\n\u001b[0;32m      3\u001b[0m client \u001b[38;5;241m=\u001b[39m OpenAI(\n\u001b[0;32m      4\u001b[0m     api_key\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msk-io42r8iyrc9aqQsm530368AdA65140CaB6C6Fd1a91C963Be\u001b[39m\u001b[38;5;124m\"\u001b[39m, \n\u001b[0;32m      5\u001b[0m     base_url\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhttp://172.30.213.120:3000/v1\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m      6\u001b[0m )\n\u001b[0;32m      8\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mllm\u001b[39m(user_query):\n",
      "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'openai'"
     ]
    }
   ],
   "source": [
    "from openai import OpenAI\n",
    "\n",
    "client = OpenAI(\n",
    "    api_key=\"sk-io42r8iyrc9aqQsm530368AdA65140CaB6C6Fd1a91C963Be\", \n",
    "    base_url=\"http://172.30.213.120:3000/v1\"\n",
    ")\n",
    "\n",
    "def llm(user_query):\n",
    "    system_prompt = f\"\"\"You are an expert at routing a user question to the relevant agent.\n",
    "    \"\"\"\n",
    "    query = user_query\n",
    "\n",
    "    completion = client.chat.completions.create(\n",
    "        model=\"HW-DeepSeek-R1-32B\",\n",
    "        messages=[{'role': 'system', 'content': system_prompt},\n",
    "                  {'role': 'user', 'content': query}],\n",
    "        )\n",
    "    return completion.choices[0].message.content\n",
    "\n",
    "llm(\"今天中午吃什么好？\")\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Marss",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.20"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
